home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / Sample Code / General App Samples / QDGX Scrolling ƒ / QDGX Scrolling Controls.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-20  |  9.4 KB  |  327 lines  |  [TEXT/MMCC]

  1. /**
  2.  --
  3.  --        App:        QuickDraw GX Scrolling
  4.  --
  5.  --        File:        GX Scrolling Controls.c
  6.  --
  7.  --
  8.  --        Comments:    This file contains all of the code required to maintain and adjust
  9.  --                    the scroll bars attached to the window. We also update the gxMapping of 
  10.  --                    our child gxViewPort as the user scrolls. This approach guarantees that 
  11.  --                    all of the shapes within our GX picture are drawn in their correct locations
  12.  --                    after scrolling.
  13.  --
  14.  --                    You can search on "GX Scrolling" to find the additions which were added to 
  15.  --                    support GX scrolling.
  16.  --
  17.  --
  18.  --        Version:    1.0     1/93    added general GX support & scrolling
  19.  --                            7/95    Converted to ThinkC 6 and new GX interfaces
  20.  --
  21.  --
  22.  --        Components:    QD GX Scrolling main.c
  23.  --                    QD GX Scrolling main.h
  24.  --                    QD GX Scrolling Controls.c
  25.  --                    QD GX Scrolling Controls.h
  26.  --                    QD GX Scrolling.π.rsrc
  27.  --
  28.  --
  29.  --        Notes:        1) Print this file in landscape for the best results
  30.  --                    2) If you are using THINK C v5.x, I have added markers to navigate the 
  31.  --                       code.
  32.  --                    3) This code was adapted and simplyified from the "DTS AE Skeleton" sample.
  33.  --
  34.  --
  35.  --        Author:        Pete "Luke" Alexander
  36.  --                    Developer Technical Support
  37.  --                    AppleLink: DEVSUPPORT
  38.  --
  39.  --        
  40.  --        ©1992 - 1993  Apple Computer, Inc. 
  41.  --        All rights reserved.
  42.  --
  43.  **/
  44.  
  45. #include <Windows.h>
  46.  
  47. #include "QDGX Scrolling main.h"
  48. #include "QDGX Scrolling Controls.h"
  49.  
  50. #include <GXGraphics.h>
  51. #include <GXMath.h>
  52.  
  53. extern     gxShape         gthePage;
  54. extern    gxViewPort        gcontentViewPort;
  55.  
  56. //
  57. // Internal Function Prototypes
  58. //
  59. void ResizeScrollBars(WindowPtr theWindow);
  60. void InvalidateScrollBars(WindowPtr theWindow);
  61. void DoControl(Point thePoint, ControlHandle theControl, short controlPart);
  62. pascal void DoControlButton(ControlHandle theControl, short controlPart);
  63. void DoScroll(WindowPtr theWindow, short hScroll, short vScroll);
  64. void AdjustScrollBar(ControlHandle theControl);
  65.  
  66.  
  67. /**----- ResizeScrollBars --------------------------------------------------------------------
  68.  --
  69.  --        This function is used when the window is resized. It resizes the scroll bars to match.
  70.  --
  71.  **/
  72. void ResizeScrollBars(WindowPtr theWindow)
  73. {    
  74.     MoveControl(((MyWindowPeek)theWindow)->vScrollBar,
  75.                 theWindow->portRect.right-(kScrollBarWidth-1),
  76.                 theWindow->portRect.top-1);
  77.     SizeControl(((MyWindowPeek)theWindow)->vScrollBar, kScrollBarWidth,
  78.                 theWindow->portRect.bottom-theWindow->portRect.top-
  79.                 (kScrollBarWidth-3));
  80.     MoveControl(((MyWindowPeek)theWindow)->hScrollBar,
  81.                 theWindow->portRect.left-1,
  82.                 theWindow->portRect.bottom-(kScrollBarWidth-1));
  83.     SizeControl(((MyWindowPeek)theWindow)->hScrollBar,
  84.                 theWindow->portRect.right-theWindow->portRect.left-
  85.                 (kScrollBarWidth-3), kScrollBarWidth);
  86.     
  87.     AdjustScrollBar(((MyWindowPeek)theWindow)->hScrollBar);    
  88.     AdjustScrollBar(((MyWindowPeek)theWindow)->vScrollBar);
  89. }
  90.  
  91.  
  92.  
  93. /**----- InvalidateScrollBars ----------------------------------------------------------------
  94.  --
  95.  --        This function is used to invalidate the area under the scroll bars for redrawing.  
  96.  --        The invalid area will be included in the next update event.
  97.  --
  98.  **/
  99. void InvalidateScrollBars(WindowPtr theWindow)
  100. {
  101.     Rect    tempRect;
  102.     
  103.     SetPort(theWindow);
  104.     
  105.     tempRect = theWindow->portRect;
  106.     tempRect.left = tempRect.right-(kScrollBarWidth-1);
  107.     InvalRect(&tempRect);
  108.     EraseRect(&tempRect);
  109.     
  110.     tempRect = theWindow->portRect;
  111.     tempRect.top = tempRect.bottom-(kScrollBarWidth-1);
  112.     InvalRect(&tempRect);
  113.     EraseRect(&tempRect);
  114. }
  115.  
  116.  
  117.  
  118. /**----- DoControl ---------------------------------------------------------------------------
  119.  --
  120.  --        This function is used when the mouse is clicked on one of the scroll bars in a document. 
  121.  --
  122.  **/
  123. void DoControl(Point thePoint, ControlHandle theControl, short controlPart)
  124. {
  125.     short        oldValue;
  126.     short        amountToScroll;
  127.     WindowPtr    theWindow;
  128.     
  129.     switch (controlPart)
  130.     {
  131.     case inUpButton:
  132.     case inDownButton:
  133.     case inPageUp:
  134.     case inPageDown:
  135.         TrackControl(theControl, thePoint, (ControlActionUPP)DoControlButton);
  136.         break;
  137.     case inThumb:
  138.         oldValue = GetCtlValue(theControl);
  139.         if (TrackControl(theControl, thePoint, nil));
  140.         {
  141.             amountToScroll = - (GetCtlValue(theControl) - oldValue);
  142.             theWindow = (**theControl).contrlOwner;
  143.             if (((MyWindowPeek)theWindow)->hScrollBar == theControl)    /* horizontal? */
  144.                 DoScroll(theWindow, amountToScroll, 0);
  145.             else
  146.                 DoScroll(theWindow, 0, amountToScroll);
  147.             AdjustScrollBar(theControl);
  148.         }
  149.         break;
  150.     }
  151. }
  152.  
  153.  
  154.  
  155. /**----- DoControlButton ---------------------------------------------------------------------
  156.  --
  157.  --        This is the actionProc for the first call to TrackControl in DoControl.  This routine
  158.  --         is called by the operating system while the mouse button is being held on the UpButton, 
  159.  --        DownButton, PageUp, and PageDown areas.  It updates the window and scroll bars.
  160.  --
  161.  **/
  162. pascal void DoControlButton(ControlHandle theControl, short controlPart)
  163. {
  164.     WindowPtr    theWindow;
  165.     long        percent;
  166.     long        direction;
  167.     short        amountToScroll;
  168.     short        theMax, theValue;
  169.  
  170.     switch (controlPart)
  171.     {
  172.     case inUpButton:
  173.         percent = 15;
  174.         direction = 1;
  175.         break;
  176.     case inDownButton:
  177.         percent = 15;
  178.         direction = -1;
  179.         break;
  180.     case inPageUp:
  181.         percent = 90;
  182.         direction = 1;
  183.         break;
  184.     case inPageDown:
  185.         percent = 90;
  186.         direction = -1;
  187.         break;
  188.     default:
  189.         return;        /* IMPORTANT:  controlPart will often be zero - take no action! */
  190.     }    
  191.  
  192.     theWindow = (**theControl).contrlOwner;
  193.     
  194.     if (theControl == ((MyWindowPeek)theWindow)->hScrollBar)    /* Horizontal */
  195.         amountToScroll = (short)((long)(theWindow->portRect.right -
  196.                                         theWindow->portRect.left -
  197.                                         (kScrollBarWidth-1)) *
  198.                                         percent/100 * direction);
  199.     else                                                        /* Vertical */
  200.         amountToScroll = (short)((long)(theWindow->portRect.bottom -
  201.                                         theWindow->portRect.top -
  202.                                         (kScrollBarWidth-1)) *
  203.                                         percent/100 * direction);
  204.  
  205.     theValue = GetCtlValue(theControl);
  206.     theMax = GetCtlMax(theControl);
  207.  
  208.     /* Don't allow scrolling past limits */
  209.     if (amountToScroll < 0)        /* scrolling right or down */
  210.     {
  211.         if ((theValue + -amountToScroll) > theMax)
  212.             amountToScroll = - (theMax - theValue);
  213.     }
  214.     else    /* scrolling left or up */
  215.     {
  216.         if ((theValue + -amountToScroll) < 0)
  217.             amountToScroll = theValue;
  218.     }
  219.  
  220.     /* Scroll the contents of the window */
  221.     if (theControl == ((MyWindowPeek)theWindow)->hScrollBar)    /* Horizontal */
  222.         DoScroll(theWindow, amountToScroll, 0);
  223.     else                                                        /* Vertical */
  224.         DoScroll(theWindow, 0, amountToScroll);
  225.  
  226.     AdjustScrollBar(theControl);
  227. }
  228.  
  229.  
  230.  
  231. /**----- DoScroll ----------------------------------------------------------------------------
  232.  --
  233.  --        This procedure scrolls the contents of a document window an amount specified in
  234.  --        hScroll and vScroll, and fills the empty space created. We also adjust the gxMapping 
  235.  --        of our child gxViewPort - "gcontentViewPort". This ensures that all of our shapes
  236.  --        are drawn in the correct location after the scrolling.
  237.  --
  238.  **/
  239.  void DoScroll(WindowPtr theWindow, short hScroll, short vScroll)
  240. {
  241.     Rect            scrollRect;
  242.     Point            scrollPt;
  243.     RgnHandle        myRgn;
  244.     gxMapping            viewPortMapping;
  245.     
  246.     if ((hScroll == 0) && (vScroll == 0)) return;
  247.  
  248.     //
  249.     //    The user has scrolled the contents of the window, therefore we need
  250.     //    to update the mapping of the "gcontentViewPort" to reflect this change.
  251.     //    If we did not adjust the mapping or transform of all of our shape(s) on
  252.     //    the page, they would be redrawn in their original unscrolled location
  253.     //    because the geometry of each gxShape has not been changed.        
  254.     //   
  255.     //    We get the mapping of "gcontentViewPort", and adjust the mapping for the
  256.     //    scroll amount. We will then reset the mapping. The "ff" macro converts
  257.     //    an integer to their fixed point equivalents.                (GX Scrolling)
  258.     //                                                                 
  259.     GXGetViewPortMapping(gcontentViewPort, &viewPortMapping);
  260.  
  261.     MoveMapping(&viewPortMapping, ff(hScroll), ff(vScroll));
  262.  
  263.     GXSetViewPortMapping(gcontentViewPort, &viewPortMapping);
  264.  
  265.  
  266.     /* Scroll contents of window except for scroll bars */
  267.     scrollRect = theWindow->portRect;
  268.     scrollRect.right -= (kScrollBarWidth-1);
  269.     scrollRect.bottom -= (kScrollBarWidth-1);
  270.  
  271.     SetPort(theWindow);
  272.     myRgn = NewRgn();
  273.     
  274.     ScrollRect(&scrollRect, hScroll, vScroll, myRgn);
  275.     SetPt(&scrollPt, hScroll, vScroll);
  276.  
  277.     AddPt(scrollPt, &((MyWindowPeek)theWindow)->origin);
  278.  
  279.     DrawWindow(theWindow);
  280.  
  281.     DisposeRgn(myRgn);
  282. }
  283.  
  284.  
  285.  
  286. /**----- AdjustScrollBar ---------------------------------------------------------------------
  287.  --
  288.  --        This function looks at the current state of the window, and adjusts the maximum, 
  289.  --        minimum, and current values for both scroll bars.
  290.  --
  291.  **/
  292. void AdjustScrollBar(ControlHandle theControl)
  293. {
  294.     WindowPtr    theWindow;
  295.     Rect        picFrame;
  296.     short        delta1, delta2;
  297.     short        theMax;
  298.  
  299.     theWindow = (**theControl).contrlOwner;
  300.     picFrame = ((MyWindowPeek)theWindow)->documentBoundsRect;
  301.     OffsetRect(&picFrame, -picFrame.left, -picFrame.top);        /* Adjust upper left to 0,0 */
  302.  
  303.     if (theControl == ((MyWindowPeek)theWindow)->hScrollBar)    /* Horizontal scroll bar */
  304.     {
  305.         delta1 = - theWindow->portRect.left - ((MyWindowPeek)theWindow)->origin.h;
  306.         delta2 = - delta1 + picFrame.right - (theWindow->portRect.right -
  307.                  theWindow->portRect.left - (kScrollBarWidth-1));
  308.     }
  309.     else    /* Vertical scroll bar */
  310.     {
  311.         delta1 = - theWindow->portRect.top - ((MyWindowPeek)theWindow)->origin.v;
  312.         delta2 = - delta1 + picFrame.bottom - (theWindow->portRect.bottom -
  313.                  theWindow->portRect.top - (kScrollBarWidth-1));
  314.     }
  315.     
  316.     theMax = 0;
  317.     if (delta1 > 0) theMax += delta1;
  318.     if (delta2 > 0) theMax += delta2;
  319.     
  320.     if (theMax > 0)
  321.     {
  322.         SetCtlMax(theControl, theMax);
  323.         SetCtlValue(theControl, delta1);
  324.     }
  325.     else
  326.         SetCtlMax(theControl, 0);
  327. }